home *** CD-ROM | disk | FTP | other *** search
- -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C)
- -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
- --
- class KNIGHT
- --|
- --| In this program a knight try to go over the n*n squares of a
- --| chessboard without pass by the same square again.
- --| The position of the knigth is given by a number.
- --|
- --| Auteur: Christophe ALEXANDRE
- --| date : Thu Mar 21 21:34:29 1996
- --
- -- Here is an example of solution on a 7 X 7 chesboard,
- -- knigth starting at position <1,1> :
- -- ----------------------
- -- | 1|28|37|24| 3|26|17|
- -- ----------------------
- -- |36|39| 2|27|18|11| 4|
- -- ----------------------
- -- |29|42|23|38|25|16| 9|
- -- ----------------------
- -- |40|35|30|19|10| 5|12|
- -- ----------------------
- -- |43|22|41|32|15| 8|47|
- -- ----------------------
- -- |34|31|20|45|48|13| 6|
- -- ----------------------
- -- |21|44|33|14| 7|46|49|
- -- ----------------------
- --
-
- inherit ANY redefine print_on end;
-
- creation {ANY}
- make
-
- feature {ANY}
-
- make is
- local
- size, line, column: INTEGER;
- do
- size := ask("Enter the chess-board size : ",3,99);
- line := ask("Enter the start line : ",1,size);
- column := ask("enter the start column : ",1,size);
- knight(size,line,column)
- end;
-
- feature {NONE}
-
- chessboard: ARRAY2[INTEGER];
-
- nb_tries: INTEGER;
-
- tl: ARRAY[INTEGER] is
- once
- Result := <<-2,-1,1,2,2,1,-1,-2>>;
- end;
-
- tc: ARRAY[INTEGER] is
- once
- Result := <<1,2,2,1,-1,-2,-2,-1>>;
- end;
-
- knight(size, line, column: INTEGER) is
- require
- size >= 3;
- 1 <= line;
- line <= size;
- 1 <= column;
- column <= size;
- do
- !!chessboard.make(1,size,1,size);
- chessboard.put(1,line,column);
- if solution(line,column) then
- print_on(std_output);
- else
- io.put_string("Sorry, there is no solution.%N");
- end;
- io.put_string("%NNumber of tries : ");
- io.put_integer(nb_tries);
- io.put_new_line;
- end; -- knight
-
- solution(line,column:INTEGER):BOOLEAN is
- local
- value,i : INTEGER;
- do
- if chessboard.count = chessboard.item(line,column) then
- Result := true;
- else
- from
- i := 1;
- value := chessboard.item(line,column);
- until
- Result or else i > 8
- loop
- Result := try(line+tl.item(i),column+tc.item(i),value);
- i := i + 1;
- end;
- end;
- end; -- solution
-
- try(line,column,value:INTEGER): BOOLEAN is
- -- try to place the knight by used cross back-tracking method
- do
- nb_tries := nb_tries + 1;
- if chessboard.valid_index(line,column) then
- if chessboard.item(line,column) = 0 then
- chessboard.put(value+1,line,column);
- Result := solution(line,column);
- if not Result then
- chessboard.put(0,line,column)
- end;
- end;
- end
- end; -- try
-
- ask(s:STRING; min, max: INTEGER):INTEGER is
- -- ask a question until its answer is all right
- local
- stop: BOOLEAN;
- do
- from
- until
- stop
- loop
- io.put_string(s);
- io.read_integer;
- Result := io.last_integer;
- if Result < min then
- io.put_string("Value too small.%N");
- elseif max < Result then
- io.put_string("Value too big.%N");
- else
- stop := true;
- end;
- end;
- end; -- ask
-
- print_on(file:STD_FILE_WRITE) is
- -- display the cheesboard
- local
- line,column : INTEGER;
- separator : STRING;
- do
- from
- !!separator.make(3*chessboard.upper1+1);
- separator.fill_with('-');
- separator.extend('%N')
- file.put_string(separator);
- line := chessboard.lower1
- until
- line > chessboard.upper1
- loop
- from
- column := chessboard.lower2
- until
- column > chessboard.upper2
- loop
- if chessboard.item(line,column) < 10 then
- file.put_string("| ");
- else
- file.put_character('|');
- end;
- file.put_integer(chessboard.item(line,column));
- column := column + 1;
- end;
- file.put_string("|%N");
- file.put_string(separator);
- line := line + 1;
- end;
- end; -- print_on
-
- end -- KNIGHT
-